#!/usr/bin/env python
# -*- coding:utf-8 -*-


class Fib(object):
    def __getitem__(self, n):  # 像list那样按照下标取出元素，需要实现__getitem__()方法：
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a

    def __iter__(self):  # 就必须实现一个__iter__()方法，该方法返回一个迭代对
        return self  # 实例本身就是迭代对象，故返回自己

    def next(self):  # 迭代方法
        self.a, self.b = self.b, self.a + self.b  # 计算下一个值
        if self.a > 100000:  # 退出循环的条件
            raise StopIteration();
        return self.a  # 返回下一个值


class Student(object):
    def __init__(self):
        self.name = 'Michael'

    def __getattr__(self, attr):  # 动态属性，当调用不存在的属性时，比如score，Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性
        if attr == 'score':
            return 99
        raise AttributeError(
            '\'Student\' object has no attribute \'%s\'' % attr)  # 让class只响应特定的几个属性，我们就要按照约定，抛出AttributeError的错误：

    def __getattr__(self, attr):
        if attr == 'age':
            return lambda: 25  # 返回函数

    def __call__(self):  # __call__()还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样
        print('My name is %s.' % self.name)


if __name__ == '__main__':
    f = Fib()
    print f[7]
    s = Student()
    print s.age()
    s()  # __call__(self)
